from django.shortcuts import render, HttpResponse, redirect
from django.views.generic import View
from systaam.models import User, XinLanSpider, Spider
from django.core.paginator import Paginator

from django.db.models import Count, Q

from .spider_start import start, key_start, zgxw_start, dan_start

from pyecharts.charts import Pie, Radar, Bar, Page
import pyecharts.options as opts


# Create your views here.


def check_login(func):  # 自定义登录验证装饰器

    def warpper(self, request, *args, **kwargs):
        is_login = request.session.get('username', False)
        if is_login:
            return func(self, request, *args, **kwargs)
        else:
            return redirect("/login")

    return warpper


class Login(View):  # 登入

    def get(self, request):
        return render(request, "login.html")

    def post(self, request):
        username = request.POST.get("username")
        password = request.POST.get("password")

        if not all([username, password]):
            self.get(request)

        try:
            user_p = User.objects.get(username=username)
        except User.DoesNotExist:
            return HttpResponse("用户不存在")

        if not user_p:
            return HttpResponse("用户不存在")

        if not user_p.password == password:
            return HttpResponse("密码错误")

        request.session["username"] = username

        return redirect("/")


class Register(View):  # 注册

    def get(self, request):
        return render(request, "regis.html")

    def post(self, request):
        username = request.POST.get("username")
        password = request.POST.get("password")
        email = request.POST.get("email")
        sex = request.POST.get('sex')

        if not all([username, password, email, sex]):
            self.get(request)

        try:
            user = User()

            user.username = username
            user.password = password
            user.sex = sex
            user.email = email

            user.phone = 0  # 无
            user.save()

            request.session['username'] = username  # 保存用户登入

            return redirect("/")
        except Exception as e:
            print(e)
            self.get(request)


class WriteOff(View):  # 注销

    @check_login
    def get(self, request):
        request.session.clear()
        return redirect("/login")


class Index(View):  # 主页
    @check_login
    def get(self, request):
        username = request.session.get("username")
        group = XinLanSpider.objects.filter(user=username).values("name").annotate(c=Count('name')).values('name', 'c')

        spider = Spider.objects.all()

        tem = {
            "username": username,
            "spider": spider,
            'group': group,
        }

        return render(request, "index.html", tem)


class AddSpider(View):  # 添加爬虫
    @check_login
    def get(self, request):

        name = request.GET.get("name")
        t = request.GET.get("t")
        s_id = request.GET.get("id")

        tem = {
            "name": name,
            "typ": t,
            "s_id": s_id,
        }
        return render(request, "addspider.html", tem)

    @check_login
    def post(self, request):
        name = request.POST.get("name")  # 爬虫名字

        key = request.POST.get("key", None)  # 关键字爬虫时候使用

        s_id = request.POST.get("s_id")  # 爬虫的id

        username = request.session.get("username")

        if not all([name, s_id, username]):
            return HttpResponse("错误，请返回进行检查")

        # 开始爬虫逻辑

        if s_id == "3":
            if key is None:
                print("单单网：")
                return HttpResponse("关键词不可以为空")
            dan_start(name, username, s_id, key)
            return redirect("/index")

        if s_id == "4":
            print("新闻网：")
            zgxw_start(name, username, s_id)
            return redirect("/index")

        if key is None:
            # 自动启动多进程调用
            start(name=name, s_id=s_id, username=username)
        else:
            key_start(name=name, s_id=s_id, username=username, key=key)

        return redirect("/index")

    def dan_spider(self):
        pass

    def china_news(self):
        pass


class Search(View):

    @check_login
    def get(self, request):

        # 用户查询的情况
        q = request.GET.get('q')
        name = request.GET.get('name')

        username = request.session.get('username')
        username = User.objects.get(username=username)  # 获得用户

        if q:
            data = XinLanSpider.objects.filter(Q(author__contains=q) | Q(content__contains=q), name=name,
                                               user_id=username)  # 多查询

            paginator = Paginator(data, 10)
            pages = paginator.page(1)  # 默认第一页

            tem = {
                'data': pages,
                'name': name,
            }
            return render(request, "search.html", tem)

        # 没有q的情况
        try:  # 处理不是数字的问题
            page = int(request.GET.get('page', None))
        except Exception as e:
            print(e)
            page = 1

        if page < 1:
            page = 1

        data = XinLanSpider.objects.filter(name=name, user_id=username)  # 多查询

        paginator = Paginator(data, 10)
        pages = paginator.page(page)

        tem = {
            'data': pages,
            'name': name,

        }

        return render(request, "search.html", tem)

    @check_login
    def post(self, request):  # 画图分析
        name = request.POST.get('name')
        username = request.session.get('username')

        data = XinLanSpider.objects.filter(user__username=username, name=name)
        group = data.values('classify').annotate(match=Count('classify')).values('classify', 'match')

        p = self.lines(group, data)
        return HttpResponse(p.render_embed())

    # 画图逻辑
    def lines(self, group, data):
        x_data = []
        y_data = []

        for gro in group:
            x_data.append(gro['classify'])
            y_data.append(gro['match'])

        data_pair = [list(z) for z in zip(x_data, y_data)]
        data_pair.sort(key=lambda x: x[1])  # 排序

        # 比重图
        p = (
            Pie()
                .add(
                "",
                data_pair,
                radius=["40%", "55%"],
                label_opts=opts.LabelOpts(
                    position="outside",
                    formatter="{a|{a}}{abg|}\n{hr|}\n {b|{b}: }{c}  {per|{d}%}  ",
                    background_color="#eee",
                    border_color="#aaa",
                    border_width=1,
                    border_radius=4,
                    rich={
                        "a": {"color": "#999", "lineHeight": 22, "align": "center"},
                        "abg": {
                            "backgroundColor": "#e3e3e3",
                            "width": "100%",
                            "align": "right",
                            "height": 22,
                            "borderRadius": [4, 4, 0, 0],
                        },
                        "hr": {
                            "borderColor": "#aaa",
                            "width": "100%",
                            "borderWidth": 0.5,
                            "height": 0,
                        },
                        "b": {"fontSize": 16, "lineHeight": 33},
                        "per": {
                            "color": "#eee",
                            "backgroundColor": "#334455",
                            "padding": [2, 4],
                            "borderRadius": 2,
                        },
                    },
                ),
            )
                .set_global_opts(title_opts=opts.TitleOpts(title="比重图", subtitle="每个主题的情况"))
        )

        # 种类第一

        max_move, max_com, max_good = 0, 0, 0

        radar_data = []

        for da in x_data:
            dar = data.filter(classify=da).order_by('-move')[0]
            if dar.move > max_move:
                max_move = dar.move

            if dar.comment > max_com:
                max_com = dar.comment

            if dar.good > max_good:
                max_good = dar.good

            radar_data.append([dar.move, dar.comment, dar.good, dar.classify])

        c = (
            Radar()
                .add_schema(
                schema=[
                    opts.RadarIndicatorItem(name="转发数", max_=max_move),
                    opts.RadarIndicatorItem(name="评论数", max_=max_com),
                    opts.RadarIndicatorItem(name="好评数", max_=max_good),
                ]

            )

                .set_series_opts(label_opts=opts.LabelOpts(is_show=False))
                .set_global_opts(
                legend_opts=opts.LegendOpts(selected_mode="single"),
                title_opts=opts.TitleOpts(title="最高转发情况", subtitle="每个分类最高转发情况"),
            )
        )

        for rad in radar_data:
            c.add(rad[-1], [rad[:-1]])

        # 用户柱状图
        user_data = data.values('author').annotate(match=Count('author')).values('author', 'match').order_by('-match')
        user_data = user_data[:5]

        user_xaxis = [da['author'] for da in user_data]
        user_match = [da['match'] for da in user_data]

        l = (
            Bar()
                .add_xaxis(user_xaxis)
                .add_yaxis("top5强", user_match)
                .set_global_opts(
                xaxis_opts=opts.AxisOpts(axislabel_opts=opts.LabelOpts(rotate=-15)),
                title_opts=opts.TitleOpts(title="Top5强", subtitle="top5风云排行版"),
            )
        )

        pag = (
            Page(layout=Page.DraggablePageLayout)
                .add(
                p,
                c,
                l
            )

        )

        return pag


class Users(View):

    @check_login
    def get(self, request):
        username = request.session.get('username')
        use = User.objects.get(username=username)

        tem = {
            'username': username,
            "phone": use.phone,
            "email": use.email,
        }

        return render(request, 'user.html', tem)

    def post(self, request):

        username = request.session.get('username')
        use = User.objects.get(username=username)

        old_password = request.POST.get('opassword')

        n_password = request.POST.get('npassword')

        nt_password = request.POST.get('ntpassword')

        if not all([old_password, n_password, nt_password]):
            return HttpResponse("输入不可为空，请返回重新输入")

        if old_password != use.password:
            return HttpResponse('密码错误')

        if n_password != nt_password:
            return HttpResponse('2个密码不一致')

        use.password = n_password
        use.save()

        return redirect('/users')
